<?php

namespace StudyBuddy\Controllers;

use StudyBuddy\WebPage;
use StudyBuddy\Paginator;
use StudyBuddy\Template\Urhere;

class Viewquestions extends WebPage {

    protected $pagerPath = '/questions';
    /**
     * Indicates the current tab
     *
     * @var string
     */
    protected $qtab = 'questions';
    /**
     * Object MongoCursor
     * @var Object MongoCursor
     */
    protected $oCursor = null;
    protected $secID = 0;
    protected $subjectID = 0;
    protected $chapterID = 0;
    protected $difID = 0;
    protected $pageID = 1;
    protected $title = '';
    protected $tagsDiv = '';
    protected $typeDiv = '';
    protected $pageHead = '';
    protected $aTplVars = array();
    /**
     * Indicates the number of matched items like
     * 123 Questions with no answers
     *
     * @var int
     */
    protected $count;
    protected $PER_PAGE = 20;
    protected $counterTaggedText = '';
    /**
     * Exclude these fields from
     * select for effeciency
     *
     * @var array
     */
    protected $aFields = array(
        'a_title' => 0,
        'sim_q' => 0,
        'a_flwrs' => 0,
        'a_comments' => 0
    );
    /**
     * Pagination links on the page
     * will not be handled by Ajax
     *
     * @var bool
     */
    protected $notAjaxPaginatable = true;

    protected function main() {

        $this->pageID = (int) $this->oRequest->get('pageID', 'i', 1);
        $this->secID = (int) $this->oRequest->get('secID', 'i', 0);
        $this->subjectID = (int) $this->oRequest->get('subjectID', 'i', 0);
        $this->chapterID = (int) $this->oRequest->get('chapterID', 'i', 0);
        $this->difID = (int) $this->oRequest->get('difID', 'i', 0);

        $this->getCursor()
                ->paginate()
                ->sendCacheHeaders();

        $this->aPageVars['title'] = $this->title;
        $this->makeTopTabs()
                ->makeFiltertab()
                ->makeQlistHeader()
                //->makeCounterBlock()
                ->makeQlistBody()
                //->makeCounterBlock()
                ->makeFollowedTags()
                ->makeRecentActivites()
                ->makeRecentTags()
                ->makeTutorListing();
    }

    /**
     * Select items according to conditions passed in GET
     * Conditions can be == 'unanswered', 'hot', 'recent' (default)
     */
    protected function getCursor() {
        $this->PER_PAGE = $this->oRegistry->Ini->PER_PAGE_QUESTIONS;

        //$aFields = array();


        $cond = $this->oRequest->get('cond', 's', 'recent');
        d('cond: ' . $cond);
        $where = array();
        /**
         * Default sort is by timestamp Descending
         * meaning most recent should be on top
         *
         */
        $sort = array('i_sticky' => -1, 'i_lm_ts' => -1);

        $this->title;

        switch ($cond) {
            /**
             * Hot is strictly per views
             */
            case 'hot':
                //$where = array('')
                break;


            /**
             * Most answers/comments/views
             * There is an activity counter
             * 1 point per view, 10 point per comment,
             * 50 points per answer
             * but still limit to 30 days
             * Cache Tags for 1 day only
             * uncache onQuestionVote, onQuestionComment
             */
            case 'active':
                $this->title = $this->_('Popular Questions');
                $this->pagerPath = '/active';

                $path = 'sec' . $this->secID . '/subject' . $this->subjectID . '/chapter' . $this->chapterID . '/diflevel' . $this->difID . '.html';

                if ($this->secID == 0 && $this->subjectID == 0 && $this->chapterID == 0 && $this->difID == 0) {
                    $path = '';
                }

                $this->typeDiv = Urhere::factory($this->oRegistry)->get('tplQtypesdiv', 'active', array('path' => $path));
                $where = array('i_ts' => array('$gt' => (time() - 604800*4)));
                $sort = array('i_ans' => -1);
                break;
            /**
             * Most votes but still
             * creation/last activity date must be
             * within reasonable time like not older than 30 days
             * Cache Tags for one day only
             * and uncache when new votes comes in
             * onQuestionVote
             */
            case 'voted':
                $this->pagerPath = '/voted';

                $path = 'sec' . $this->secID . '/subject' . $this->subjectID . '/chapter' . $this->chapterID . '/diflevel' . $this->difID . '.html';

                if ($this->secID == 0 && $this->subjectID == 0 && $this->chapterID == 0 && $this->difID == 0) {
                    $path = '';
                }

                d('cp');
                $this->title = $this->_('Questions with highest votes in past 1 month');
                $this->typeDiv = Urhere::factory($this->oRegistry)->get('tplQtypesdiv', 'voted', array('path' => $path));
                $where = array('i_ts' => array('$gt' => (time() - 604800*4)));
                $sort = array('i_votes' => -1);
                break;

            case 'difficult':
                $this->pagerPath = '/difficult';

                $path = 'sec' . $this->secID . '/subject' . $this->subjectID . '/chapter' . $this->chapterID . '/diflevel' . $this->difID . '.html';

                if ($this->secID == 0 && $this->subjectID == 0 && $this->chapterID == 0 && $this->difID == 0) {
                    $path = '';
                }

                d('cp');
                $this->title = $this->_('Questions with highest difficult in past 1 month');
                $this->typeDiv = Urhere::factory($this->oRegistry)->get('tplQtypesdiv', 'difficult', array('path' => $path));
                $where = array('i_ts' => array('$gt' => (time() - 604800*4)));
                $sort = array('dif' => -1);
                break;
                
            case 'verified':
                $this->pagerPath = '/verified';

                $path = 'sec' . $this->secID . '/subject' . $this->subjectID . '/chapter' . $this->chapterID . '/diflevel' . $this->difID . '.html';

                if ($this->secID == 0 && $this->subjectID == 0 && $this->chapterID == 0 && $this->difID == 0) {
                    $path = '';
                }

                d('cp');
                $this->title = $this->_('Questions with verified in past 1 month');
                $this->typeDiv = Urhere::factory($this->oRegistry)->get('tplQtypesdiv', 'verified', array('path' => $path));
                $where = array('status' => 'accptd');
                $sort = array('dif' => -1);
                break;

            /**
             * Default is all questions
             * Tags are qrecent
             * uncache qrecent onNewQuestion only!
             */
            default:
                $this->title = $this->_('All questions');

                $path = 'sec' . $this->secID . '/subject' . $this->subjectID . '/chapter' . $this->chapterID . '/diflevel' . $this->difID . '.html';

                if ($this->secID == 0 && $this->subjectID == 0 && $this->chapterID == 0 && $this->difID == 0) {
                    $path = '';
                }

                $this->typeDiv = Urhere::factory($this->oRegistry)->get('tplQtypesdiv', 'newest', array('path' => $path));
        }

        /**
         * Exclude deleted items
         */
        $where['i_del_ts'] = null;

        if ($this->secID > 0) {
            $where['level'] = "$this->secID";
        }
        if ($this->subjectID > 0) {
            $where['subject'] = "$this->subjectID";
        }
        if ($this->chapterID > 0) {
            $where['chapter'] = "$this->chapterID";
        }
        if ($this->difID > 0) {
            if ($this->difID == 1) {
                $where['dif'] = null;
            } else {
                $where['dif'] = "$this->difID";
            }
        }


        /**
         * @todo for effecienty explicitely specify which
         * doc fields to select or at least tell
         * which NOT to select, for example we don't need
         * a_edited and a_title
         *
         */
        $this->oCursor = $this->oRegistry->Mongo->QUESTIONS->find($where);
        d('$this->oCursor: ' . gettype($this->oCursor));
        $this->oCursor->sort($sort);

        return $this;
    }

    /**
     * Create a paginator object
     * and paginate results of select
     *
     * @return object $this
     */
    protected function paginate() {
        $path = '/sec' . $this->secID . '/subject' . $this->subjectID . '/chapter' . $this->chapterID . '/diflevel' . $this->difID;

        if ($this->secID == 0 && $this->subjectID == 0 && $this->chapterID == 0 && $this->difID == 0) {
            $path = '';
        }

        d('paginating with $this->pagerPath: ' . $this->pagerPath);
        $oPaginator = Paginator::factory($this->oRegistry);
        $oPaginator->paginate($this->oCursor, $this->PER_PAGE, array('path' => $this->pagerPath . $path));

        $this->pagerLinks = $oPaginator->getLinks();

        d('$this->pagerLinks: ' . $this->pagerLinks);

        return $this;
    }

    /**
     * Generates html of the "recent tags"
     * block
     *
     * If user is logged in AND
     * has 'followed tags' then don't use
     * cache and instead do this:
     * get array of recent tags, sort in a way
     * than user's tags are on top and then render
     * This way user's tags will always be on top
     * at a cost of couple of milliseconds we get
     * a nice personalization that does increase
     * the click rate!
     *
     * @return object $this
     */
    protected function makeRecentTags() {

        $aUserTags = $this->oRegistry->Viewer['a_f_t'];
        if (!empty($aUserTags)) {
            $s = $this->getSortedRecentTags($aUserTags);
        } else {
            $s = $this->oRegistry->Cache->get('qrecent');
        }

        $tags = \tplBoxrecent::parse(array('tags' => $s, 'title' => $this->_('Recent Tags')));
        d('cp');
        $this->aPageVars['tags'] = $tags;

        return $this;
    }

    //hoangto tutor listing
    protected function makeTutorListing() {

        $s = $this->getSortedTutors();
        $tutors = \tplTutorBox::parse(array('tutors' => $s, 'title' => $this->_('Tutor Listing')));
        d('cp');
        $this->aPageVars['tutors'] = $tutors;

        return $this;
    }

    //hoangto tutor listing
    protected function makeRecentActivites() {

        $s = $this->getSortedActivities();
        $tutors = \tplActivityBox::parse(array('ractivites' => $s, 'title' => $this->_('Recent activities')));
        d('cp');
        $this->aPageVars['activities'] = $tutors;

        return $this;
    }

    /**
     * @todo finish this
     *
     * Must peek at last item in cursor and get
     * its' timestamp, then rewind cursor back
     * Use usual uid, usergroup, pageID, lang for etag
     * maybe also use reputation score now
     */
    protected function sendCacheHeaders() {


        return $this;
    }

    protected function makeTopTabs() {
        $guest = null;
        if($this->oRegistry->Viewer->isGuest()) {
            $guest['link_ask'] = '#'; // 13
            $guest['link_ask_click'] = ' onclick="oSL.getQuickRegForm()"'; //14
        }
        $tabs = Urhere::factory($this->oRegistry)->get('tplToptabs', $this->qtab, $guest);
        $this->aPageVars['topTabs'] = $tabs;

        return $this;
    }

    protected function makeFiltertab() {

        $filterTab = \tplFiltertab::parse(array('level' => $this->buildSec(), 'subject' => $this->buildSubject(), 'chapter' => $this->buildChapter(), 'subjectID' => $this->subjectID, 'dif' => $this->buildDif(), 'chapterID' => $this->chapterID, 'difID' => $this->difID, 'secID' => $this->secID));
        $this->aPageVars['filterTabs'] = $filterTab;

        return $this;
    }

    protected function makeQlistHeader() {

        $this->aPageVars['qheader'] = '<h1>' . $this->title . '</h1>';

        return $this;
    }

    protected function makeQlistBody() {

        $uid = $this->oRegistry->Viewer->getUid();

        $aUserTags = $this->oRegistry->Viewer['a_f_t'];
        $showDeleted = $this->oRegistry->Viewer->isModerator();
        $contributed = $this->_('You have contributed to this question');
        $following = $this->_('You are following this question');
        $asked = $this->_('Asked');
        $latestBy = $this->_('Latest answer by');
        $toggle = $this->_('Toggle Unread/Read Status');
        $imagepreview = '';

        $func = function(&$a) use($uid, $aUserTags, $showDeleted, $following, $contributed, $asked, $latestBy, $toggle, $imagepreview) {

                    if ($uid == $a['i_uid'] || (!empty($a['a_uids']) && in_array($uid, $a['a_uids']))) {
                        $a['dot'] = '<div class="fr pad2"><span class="ico person ttt" title="' . $contributed . '">&nbsp;</span></div>';
                    }

                    if (!empty($a['a_flwrs']) && in_array($uid, $a['a_flwrs'])) {
                        $a['following_q'] = '<div class="fr pad2"><span class="icoc check ttt" title="' . $following . '">&nbsp;</span></div>';
                    }

                    /**
                     * Add special flag if user following
                     * at least one of the tag of this question.
                     */
                    if (count(array_intersect($a['a_tags'], $aUserTags)) > 0) {
                        $a['following_tag'] = '  followed_tag';
                    }

                    $a['asked'] = $asked;
                    $a['toggle'] = $toggle;
                    $a['latest_by'] = $latestBy;
                    $a['imagepreview'] = $imagepreview;
                };


        $sQdivs = \tplQrecent::loop($this->oCursor, true, $func);

        $sQlist = \tplQlist::parse(array($this->typeDiv, $sQdivs, $this->pagerLinks, $this->notAjaxPaginatable), false);
        $this->aPageVars['body'] = $sQlist;
        d('cp');
        /**
         * In case of Ajax can just send out sQlist as result
         */
        return $this;
    }

    /**
     *
     *
     */
    protected function makeCounterBlock() {
        $this->aPageVars['topRight'] = \tplCounterblock::parse(array($this->oCursor->count(), $this->_('Number of Questions'), ''), false);

        return $this;
    }

    /**
     * Creates div with tags user follows
     * The values from the tag links in that div
     * are also used by Javascript to highlight
     * the divs with questions that contain these tags
     *
     * This block is only added if user follows
     * at least one tag
     *
     * @return object $this
     */
    protected function makeFollowedTags() {

        $aFollowed = $this->oRegistry->Viewer['a_f_t'];
        d('$aFollowed: ' . print_r($aFollowed, 1));
        if (!empty($aFollowed)) {

            $this->aPageVars['side'] = '<div id="usrtags" class="fl cb w90 pl10 mb10"><div class="pad8 lg cb fr rounded3 w90"><h4>' .
                    $this->_('Tags you follow') . '</h4>' .
                    \tplFollowedTags::loop($aFollowed, false) . '</div></div>';
        }

        return $this;
    }

    /**
     * Creates html for the recent tags block
     * but user's followed tags will always be
     * on top
     *
     *
     * @param array $aUserTags array of tags user follows
     *
     * @return string html with parsed tags links
     */
    protected function getSortedRecentTags(array $aUserTags, $type = 'recent') {

        $limit = 9;
        if ('unanswered' === $type) {
            //$cur = $this->oRegistry->Mongo->UNANSWERED_TAGS->find(array(), array('tag', 'i_count'))->sort(array('i_ts' => -1))->limit($limit);
            $cur = $this->oRegistry->Mongo->UNANSWERED_TAGS->find(array(), array('tag', 'i_count'))->sort(array('i_count' => -1))->limit($limit);
        } else {
            //$cur = $this->oRegistry->Mongo->QUESTION_TAGS->find(array('i_count' => array('$gt' => 0)), array('tag', 'i_count'))->sort(array('i_ts' => -1))->limit($limit);
            $cur = $this->oRegistry->Mongo->QUESTION_TAGS->find(array('i_count' => array('$gt' => 0)), array('tag', 'i_count'))->sort(array('i_count' => -1))->limit($limit);
        }

        d('got ' . $cur->count(true) . ' tag results');
        $aTags = iterator_to_array($cur);

        d('aTags: ' . print_r($aTags, 1));

        if (!empty($aTags)) {
            usort($aTags, function($a, $b) use ($aUserTags) {
                        return (in_array($a['tag'], $aUserTags)) ? -1 : 1;
                    });
        };

        d('$aTags now: ' . print_r($aTags, 1));
        $html = ('unanswered' === $type) ? \tplUnanstags::loop($aTags) : \tplLinktag::loop($aTags);

        d('html recent tags: ' . $html);

        return '<div class="tag"><ul>' . $html . '</ul></div>';
    }

    //hoangto tutor listing loop
    protected function getSortedTutors() {

        $cur = $this->oRegistry->Mongo->USERS->find(array('tmp_role' => 'tutor'))->sort(array('experience' => -1))->limit(9);

        $canTeach = '';

        $func = function(&$a) use($canTeach) {
                    $a['canTeach'] = $canTeach;
                };

        $tutors = \tplTutorListing::loop($cur, true, $func);

        return $tutors;
    }

    //hoangto tutor listing loop
    protected function getSortedActivities() {

        $act_link = '';
        $badges = '';

        $func = function(&$a) use($act_link, $badges) {
                    $a['act_link'] = $act_link;
                    $a['badges'] = $badges;
                };

        $cur = $this->oRegistry->Mongo->ACTIVITIES->find()->sort(array('i_ts' => -1))->limit(5);

        $tutors = \tplActivityList::loop($cur, true, $func);

        return $tutors;
    }

    protected function buildSec() {
        $s = '';
        $current = $this->secID;
        $sec = array(
            1 => 'Sec 1',
            2 => 'Sec 2',
            3 => 'Sec 3&4'
        );

        $tpl = '<option value="%1$s"%2$s>%3$s</option>';
        foreach ($sec as $key => $val) {
            $selected = ($key == $current) ? ' selected="selected"' : '';
            $s .= vsprintf($tpl, array($key, $selected, $val));
        }

        return $s;
    }

    protected function buildSubject() {
        $s = '';
        $current = $this->subjectID;
        
        $subject1 = array(
            4 => 'Maths',
            5 => 'Science'
        );
        $subject2 = array(
            6 => 'Maths',
            7 => 'Science'
        );
        $subject3 = array(
            1 => 'E Maths',
            2 => 'A Maths',
            3 => 'Physics'
        );

        $subject = null;
        switch ($this->secID) {
            case 1:
                $subject = $subject1;
                break;
            case 2:
                $subject = $subject2;
                break;
            case 3:
                $subject = $subject3;
                break;
            default:
                break;
        }

        $tpl = '<option value="%1$s"%2$s>%3$s</option>';
        if($subject!=null) {
            foreach ($subject as $key => $val) {
                $selected = ($key == $current) ? ' selected="selected"' : '';
                $s .= vsprintf($tpl, array($key, $selected, $val));
            }
        }

        return $s;
    }

    protected function buildChapter() {
        $s = '';
        $current = $this->chapterID;

        $e_maths = array(
            1 => 'Factorisation',
            2 => 'Numbers and four operations',
            3 => 'Inequalities',
            4 => 'Indices',
            5 => 'Ratio, rate and proportion',
            6 => 'Percentage',
            7 => 'Speed',
            8 => 'Algebra',
            9 => 'Functions and graphs',
            10 => 'Solutions of equations',
            11 => 'Applied maths',
            12 => 'Set language and notation',
            13 => 'Matrices',
            14 => 'Angles, triangles and polygons',
            15 => 'Congruence and similarity',
            16 => 'Properties of circles',
            17 => 'Pythagoras\' theorem',
            18 => 'Trigonometry',
            19 => 'Mensuration',
            20 => 'Coordinate geometry',
            21 => 'Vectors',
            22 => 'Data handling',
            23 => 'Data analysis',
            24 => 'Probability'
        );

        $a_maths = array(
            1 => 'Quadratic equations and inequalities',
            2 => 'Indices and surds',
            3 => 'Polynomials',
            4 => 'Simultaneous equations',
            5 => 'Partial fractions',
            6 => 'Binomial expansions',
            7 => 'Exponential, logarithmic and modulus functions',
            8 => 'Trigonometry',
            9 => 'Coordinate geometry',
            10 => 'Plane geometry',
            11 => 'Differentiation',
            12 => 'Integration'
        );

        $physics = array(
            1 => 'Physical Quantities, Units and Measurements',
            2 => 'Kinematics',
            3 => 'Forces',
            4 => 'Mass, Weight and Density',
            5 => 'Moments',
            6 => 'Work, Energy and Power',
            7 => 'Pressure',
            8 => 'Kinetic Model of Matter',
            9 => 'Heat Capacity and Latent Heat',
            10 => 'Transfer of Thermal Energy',
            11 => 'Temperature',
            12 => 'Thermal Properties of Matter',
            13 => 'Waves',
            14 => 'Sound',
            15 => 'Reflection and Refraction',
            16 => 'Lenses',
            17 => 'Electromagnetic Spectrum',
            18 => 'Current Electricity',
            19 => 'Static Electricity',
            20 => 'D.C. Circuits',
            21 => 'Practical Electricity',
            22 => 'Magnetism',
            23 => 'Electromagnetism',
            24 => 'Electromagnetic Induction',
            25 => 'Transformers and C.R.O.'
        );
        
        $maths1 = array(
            1 => 'Primes and Prime Factors',
            2 => 'Real Numbers',
            3 => 'Algebra',
            4 => 'Solving equations and inequalities',
            5 => 'Ratio, Rate and Percentage',
            6 => 'Statistics',
            7 => 'Cartesian Coordinates and Linear Functions',
            8 => 'Angles and Geometrical Constructions',
            9 => 'Triangles, Quadrilaterals and Polygons',
            10 => 'Perimeter and Area of Plane Figures',
            11 => 'Volume and Surface Area of Solids'
        );
        $science1 = array(
            1 => 'Introducing Science',
            2 => 'Scientific Inquiry',
            3 => 'Basic Science Measurements',
            4 => 'Speed and Density',
            5 => 'Classifying Living Things',
            6 => 'Classification of Matter',
            7 => 'Elements, Compounds and Mixtures',
            8 => 'Solutions and Suspensions',
            9 => 'Particulate Model of Matter',
            10 => 'Atoms, Molecules and Ions',
            11 => 'Cells and Organisms',
            12 => 'Movement of Substances',
            13 => 'Transport in Living Things',
            14 => 'Digestion',
            15 => 'Sexual Reproduction in Human Beings',
            16 => 'Issues on Sex'
        );
        $maths2 = array(
            1 => 'Proportion',
            2 => 'Geometry',
            3 => 'Algebraic Expressions and Equations',
            4 => 'Quadratic Expressions and Equations',
            5 => 'Graphs',
            6 => 'Pythagoras\' Theorem',
            7 => 'Mensuration',
            8 => 'Statistics',
            9 => 'Sets, Probability'
        );
        $science2 = array(
            1 => 'Energy Around Us',
            2 => 'Photosynthesis and Respiration',
            3 => 'Light and Colour',
            4 => 'Introducing Electricity',
            5 => 'Household Electricity',
            6 => 'Force and Pressure',
            7 => 'Forces at Work',
            8 => 'Effects of Heat Energy',
            9 => 'Transmission of Heat',
            10 => 'Changing Matter',
            11 => 'Living Things in an Ecosystem'
        );

        $chapter = null;
        switch ($this->subjectID) {
            case 1:
                $chapter = $e_maths;
                break;
            case 2:
                $chapter = $a_maths;
                break;
            case 3:
                $chapter = $physics;
                break;
            
            case 4:
                $chapter = $maths1;
                break;
            case 5:
                $chapter = $science1;
                break;
            case 6:
                $chapter = $maths2;
                break;
            case 7:
                $chapter = $science2;
                break;
            default:
                break;
        }

        $tpl = '<option value="%1$s"%2$s>%3$s</option>';
        if ($chapter != null) {
            foreach ($chapter as $key => $val) {
                $selected = ($key == $current) ? ' selected="selected"' : '';
                $s .= vsprintf($tpl, array($key, $selected, $val));
            }
        }

        return $s;
    }

    protected function buildDif() {
        $s = '';
        $current = $this->difID;
        $subject = array(
            1 => '1',
            2 => '2',
            3 => '3',
            4 => '4',
            5 => '5'
        );

        $tpl = '<option value="%1$s"%2$s>%3$s</option>';
        foreach ($subject as $key => $val) {
            $selected = ($key == $current) ? ' selected="selected"' : '';
            $s .= vsprintf($tpl, array($key, $selected, $val));
        }

        return $s;
    }

}
